package cn.xuexiluxian.open.admin.controller.system;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.xuexiluxian.open.common.annotation.Log;
import cn.xuexiluxian.open.common.annotation.RepeatSubmit;
import cn.xuexiluxian.open.common.enums.BusinessType;
import cn.xuexiluxian.open.system.model.entity.SystemRoleMenu;
import cn.xuexiluxian.open.system.service.ISystemRoleMenuService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.xuexiluxian.open.common.enums.ResultStatusCodeEnum;
import cn.xuexiluxian.open.common.response.ResponseResult;
import cn.xuexiluxian.open.common.utils.SecurityUtil;
import cn.xuexiluxian.open.system.model.dto.SystemMenuDTO;
import cn.xuexiluxian.open.system.model.entity.SystemMenu;
import cn.xuexiluxian.open.system.model.entity.SystemUnit;
import cn.xuexiluxian.open.system.model.req.SystemMenuREQ;
import cn.xuexiluxian.open.system.service.ISystemMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * 菜单权限
 */
@Slf4j
@RestController
@RequestMapping("system/menu")
public class SystemMenuController {
    @Autowired
    private ISystemMenuService systemMenuService;
    @Autowired
    private ISystemRoleMenuService systemRoleMenuService;

    /**
     * 分页查询菜单权限
     * @param page
     * @param params
     * @return
     */
    @GetMapping(value = "page")
    @Log(title = "菜单权限", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:menu:page')")
    public ResponseResult page(Page page, SystemMenuREQ params) {
        Page<SystemMenu> pageList = systemMenuService.pageList(page, params);
        return ResponseResult.ok(pageList);
    }

    /**
     * 菜单树
     * @return
     */
    @GetMapping(value = "tree")
    @Log(title = "菜单权限", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:menu:page')")
    public ResponseResult tree() {
        LambdaQueryWrapper<SystemMenu> queryWrapper = Wrappers.<SystemMenu>lambdaQuery()
                .eq(true, SystemMenu::getEnabled, 1)
                .ne(true, SystemMenu::getType, 2);

        List<SystemMenu> list = systemMenuService.list(queryWrapper);

        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setWeightKey("sort");
        List<Tree<String>> trees = TreeUtil.build(list, "-1", treeNodeConfig, (treeNode, tree) -> {
            tree.setId(treeNode.getId());
            tree.setParentId(treeNode.getParentId());
            tree.setName(treeNode.getName());
            tree.setWeight(treeNode.getSort());
            // 扩展属性 ...
            tree.putExtra("path", treeNode.getPath());
            tree.putExtra("query", treeNode.getQuery());
            tree.putExtra("component", treeNode.getComponent());
            tree.putExtra("cache", treeNode.getCache());
            tree.putExtra("type", treeNode.getType());
            tree.putExtra("visible", treeNode.getVisible());
            tree.putExtra("enabled", treeNode.getEnabled());
            tree.putExtra("perms", treeNode.getPerms());
            tree.putExtra("icon", treeNode.getIcon());
            tree.putExtra("remark", treeNode.getRemark());
            tree.putExtra("createTime", treeNode.getCreateTime());
        });
        return ResponseResult.ok(trees);
    }

    /**
     * 删除菜单权限
     * @param id
     * @return
     */
    @RepeatSubmit
    @GetMapping("delete/{id}")
    @Log(title = "菜单权限", businessType = BusinessType.DELETE)
    @PreAuthorize("@permission.hasPermission('system:menu:delete')")
    public ResponseResult delete(@PathVariable String id){
        if(StrUtil.isBlank(id)){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        QueryWrapper<SystemMenu> queryWrapper = new QueryWrapper<SystemMenu>();
        queryWrapper.eq("parent_id", id);
        List<SystemMenu> list = systemMenuService.list(queryWrapper);
        if(list != null && list.size() > 0){
            return ResponseResult.error(ResultStatusCodeEnum.DATA_HAS_CHILDREN);
        }

        QueryWrapper<SystemRoleMenu> queryWrapper1 = new QueryWrapper<SystemRoleMenu>();
        queryWrapper1.eq("menu_id", id);
        List<SystemRoleMenu> roleMenus = systemRoleMenuService.list(queryWrapper1);
        if(roleMenus != null && roleMenus.size() > 0){
            return ResponseResult.error(ResultStatusCodeEnum.DATA_HAS_RESOURCES);
        }

        boolean b = systemMenuService.removeById(id);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.HTTP_ERROR);
    }

    /**
     * 菜单权限详情
     * @param id
     * @return
     */
    @GetMapping("get/{id}")
    @Log(title = "菜单权限", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:menu:get')")
    public ResponseResult get(@PathVariable String id){
        if(StrUtil.isBlank(id)){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        SystemMenu systemMenu = systemMenuService.getById(id);
        if(systemMenu != null){
            return ResponseResult.ok(systemMenu);
        }
        return ResponseResult.error(ResultStatusCodeEnum.DATA_NO_EXIST);
    }

    /**
     * 添加菜单权限
     * @param systemMenuDTO
     * @return
     */
    @RepeatSubmit
    @PostMapping("add")
    @Log(title = "菜单权限", businessType = BusinessType.INSERT)
    @PreAuthorize("@permission.hasPermission('system:menu:add')")
    public ResponseResult add(@RequestBody SystemMenuDTO systemMenuDTO){
        String userId = SecurityUtil.getUserId();

        SystemMenu systemMenu = new SystemMenu();
        BeanUtils.copyProperties(systemMenuDTO, systemMenu);
        systemMenu.setId(IdUtil.getSnowflakeNextIdStr());
        systemMenu.setCreateBy(userId);
        systemMenu.setCreateTime(new Date());

        boolean b = systemMenuService.save(systemMenu);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.HTTP_ERROR);
    }

    /**
     * 修改菜单权限
     * @param systemMenuDTO
     * @return
     */
    @RepeatSubmit
    @PostMapping("update")
    @Log(title = "菜单权限", businessType = BusinessType.UPDATE)
    @PreAuthorize("@permission.hasPermission('system:menu:update')")
    public ResponseResult update(@RequestBody SystemMenuDTO systemMenuDTO){
        String userId = SecurityUtil.getUserId();
        if(systemMenuDTO == null || StrUtil.isBlank(systemMenuDTO.getId())){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        SystemMenu systemMenu = new SystemMenu();
        BeanUtils.copyProperties(systemMenuDTO, systemMenu);
        systemMenu.setUpdateBy(userId);
        systemMenu.setUpdateTime(new Date());

        boolean b = systemMenuService.updateById(systemMenu);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.HTTP_ERROR);
    }
}
